<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>简谱打谱软件</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/jspdf@2.5.1/dist/jspdf.umd.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
  
  <!-- 配置Tailwind自定义主题 -->
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            primary: '#165DFF',
            secondary: '#36D399',
            neutral: '#F8FAFC',
            'neutral-dark': '#334155'
          },
          fontFamily: {
            sans: ['Inter', 'system-ui', 'sans-serif'],
            mono: ['JetBrains Mono', 'monospace']
          }
        }
      }
    }
  </script>
  
  <style type="text/tailwindcss">
    @layer utilities {
      .content-auto {
        content-visibility: auto;
      }
      .sheet-line {
        height: 1.5px;
        background-color: #334155;
        margin: 0.5rem 0;
      }
      .note-input {
        @apply border border-gray-300 rounded px-2 py-1 text-center w-10 transition-all duration-200;
      }
      .note-input:focus {
        @apply outline-none ring-2 ring-primary/50 border-primary;
      }
      .btn {
        @apply px-4 py-2 rounded-md transition-all duration-200 font-medium;
      }
      .btn-primary {
        @apply bg-primary text-white hover:bg-primary/90 focus:ring-2 focus:ring-primary/50;
      }
      .btn-secondary {
        @apply bg-secondary text-white hover:bg-secondary/90 focus:ring-2 focus:ring-secondary/50;
      }
      .btn-outline {
        @apply border border-gray-300 hover:bg-gray-100 focus:ring-2 focus:ring-gray-300/50;
      }
      .btn-danger {
        @apply bg-red-500 text-white hover:bg-red-600 focus:ring-2 focus:ring-red-500/50;
      }
      .section-card {
        @apply bg-white rounded-lg shadow-md p-4 mb-4 transition-all duration-300 hover:shadow-lg;
      }
      .input-field {
        @apply w-full border border-gray-300 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary/50 focus:border-primary;
      }
    }
  </style>
</head>
<body class="bg-gray-50 min-h-screen flex flex-col">
  <!-- 顶部导航栏 -->
  <header class="bg-white shadow-sm sticky top-0 z-10">
    <div class="container mx-auto px-4 py-3 flex justify-between items-center">
      <div class="flex items-center space-x-2">
        <i class="fa fa-music text-primary text-2xl"></i>
        <h1 class="text-xl font-bold text-neutral-dark">简谱打谱软件</h1>
      </div>
      
      <div class="flex items-center space-x-3">
        <button id="new-btn" class="btn btn-outline">
          <i class="fa fa-file-o mr-1"></i> 新建
        </button>
        <button id="save-btn" class="btn btn-outline">
          <i class="fa fa-save mr-1"></i> 保存
        </button>
        <button id="export-btn" class="btn btn-secondary">
          <i class="fa fa-download mr-1"></i> 导出PDF
        </button>
      </div>
    </div>
  </header>

  <!-- 主内容区 -->
  <main class="flex-grow container mx-auto px-4 py-6 grid grid-cols-1 lg:grid-cols-3 gap-6">
    <!-- 左侧控制面板 -->
    <div class="lg:col-span-1 space-y-4">
      <!-- 基本信息 -->
      <div class="section-card">
        <h2 class="text-lg font-semibold mb-3 flex items-center">
          <i class="fa fa-info-circle text-primary mr-2"></i> 基本信息
        </h2>
        <div class="space-y-3">
          <div>
            <label class="block text-sm font-medium text-gray-700 mb-1">曲名</label>
            <input type="text" id="song-title" class="input-field" placeholder="请输入曲名">
          </div>
          <div>
            <label class="block text-sm font-medium text-gray-700 mb-1">作曲</label>
            <input type="text" id="composer" class="input-field" placeholder="请输入作曲者">
          </div>
          <div>
            <label class="block text-sm font-medium text-gray-700 mb-1">作词</label>
            <input type="text" id="lyricist" class="input-field" placeholder="请输入作词者">
          </div>
          <div class="grid grid-cols-2 gap-3">
            <div>
              <label class="block text-sm font-medium text-gray-700 mb-1">调号</label>
              <select id="key-signature" class="input-field">
                <option value="C">C调</option>
                <option value="D">D调</option>
                <option value="E">E调</option>
                <option value="F">F调</option>
                <option value="G">G调</option>
                <option value="A">A调</option>
                <option value="B">B调</option>
              </select>
            </div>
            <div>
              <label class="block text-sm font-medium text-gray-700 mb-1">拍号</label>
              <select id="time-signature" class="input-field">
                <option value="2/4">2/4</option>
                <option value="3/4">3/4</option>
                <option value="4/4">4/4</option>
                <option value="3/8">3/8</option>
                <option value="6/8">6/8</option>
              </select>
            </div>
          </div>
          <div>
            <label class="block text-sm font-medium text-gray-700 mb-1">速度</label>
            <div class="flex items-center">
              <input type="range" id="tempo" min="40" max="200" value="120" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
              <span id="tempo-value" class="ml-2 text-sm font-medium">120 BPM</span>
            </div>
          </div>
        </div>
      </div>

      <!-- 简谱输入 -->
      <div class="section-card">
        <h2 class="text-lg font-semibold mb-3 flex items-center">
          <i class="fa fa-pencil text-primary mr-2"></i> 简谱输入
        </h2>
        
        <div class="space-y-3">
          <div>
            <label class="block text-sm font-medium text-gray-700 mb-1">歌词</label>
            <textarea id="lyrics" rows="4" class="input-field" placeholder="请输入歌词，每行一句"></textarea>
          </div>
          
          <div>
            <label class="block text-sm font-medium text-gray-700 mb-1">简谱符号</label>
            <div class="grid grid-cols-7 gap-2 mb-3" id="note-pad">
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="1">1</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="2">2</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="3">3</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="4">4</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="5">5</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="6">6</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="7">7</button>
              
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="·1">˙1</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="·2">˙2</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="·3">˙3</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="·4">˙4</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="·5">˙5</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="·6">˙6</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="·7">˙7</button>
              
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="1·">1˙</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="2·">2˙</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="3·">3˙</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="4·">4˙</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="5·">5˙</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="6·">6˙</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="7·">7˙</button>
              
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="0">0</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="|">|</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="||">||</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="∥">∥</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="·">·</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="-">-</button>
              <button class="note-btn p-2 border rounded text-center hover:bg-gray-100 transition-colors" data-value="_">_</button>
            </div>
          </div>
          
          <div>
            <label class="block text-sm font-medium text-gray-700 mb-1">当前小节</label>
            <div id="current-bar" class="flex flex-wrap gap-1 p-2 border rounded min-h-[40px]">
              <span class="text-gray-400">点击上方音符添加...</span>
            </div>
          </div>
          
          <div class="flex justify-between space-x-2">
            <button id="add-bar-btn" class="btn btn-primary flex-1">
              <i class="fa fa-plus mr-1"></i> 添加小节
            </button>
            <button id="clear-bar-btn" class="btn btn-outline">
              <i class="fa fa-trash-o mr-1"></i> 清空
            </button>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 右侧预览区 -->
    <div class="lg:col-span-2">
      <div class="section-card h-full">
        <div class="flex justify-between items-center mb-4">
          <h2 class="text-lg font-semibold flex items-center">
            <i class="fa fa-eye text-primary mr-2"></i> 简谱预览
          </h2>
          <div class="flex space-x-2">
            <button id="zoom-in-btn" class="p-1.5 rounded hover:bg-gray-100 transition-colors">
              <i class="fa fa-search-plus text-neutral-dark"></i>
            </button>
            <button id="zoom-out-btn" class="p-1.5 rounded hover:bg-gray-100 transition-colors">
              <i class="fa fa-search-minus text-neutral-dark"></i>
            </button>
            <button id="reset-zoom-btn" class="p-1.5 rounded hover:bg-gray-100 transition-colors">
              <i class="fa fa-refresh text-neutral-dark"></i>
            </button>
          </div>
        </div>
        
        <div id="sheet-preview" class="bg-white p-6 border border-gray-200 rounded-lg overflow-auto min-h-[700px] max-w-4xl mx-auto" style="zoom: 80%">
          <div id="sheet-content" class="font-mono">
            <!-- 简谱内容将在这里动态生成 -->
            <div class="text-center mb-6">
              <h1 id="preview-title" class="text-2xl font-bold mb-1">歌曲标题</h1>
              <div class="flex justify-center space-x-6 text-sm text-gray-600 mb-2">
                <span>作曲：<span id="preview-composer">作曲者</span></span>
                <span>作词：<span id="preview-lyricist">作词者</span></span>
              </div>
              <div class="flex justify-center space-x-4 text-sm text-gray-600">
                <span id="preview-key">1=C</span>
                <span id="preview-time">4/4</span>
                <span id="preview-tempo">♩=120</span>
              </div>
            </div>
            
            <div id="preview-bars" class="space-y-6">
              <!-- 小节将在这里动态生成 -->
              <div class="text-center text-gray-400 italic py-12">
                请从左侧面板添加简谱内容...
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </main>

  <!-- 页脚 -->
  <footer class="bg-white border-t border-gray-200 py-4">
    <div class="container mx-auto px-4 text-center text-sm text-gray-500">
      <p>简谱打谱软件 &copy; 2025 | 使用 HTML, JavaScript 和 Tailwind CSS 构建</p>
    </div>
  </footer>

  <!-- 导出PDF确认对话框 -->
  <div id="export-modal" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 hidden">
    <div class="bg-white rounded-lg shadow-xl p-6 max-w-md w-full mx-4 transform transition-all duration-300 scale-95 opacity-0" id="modal-content">
      <h3 class="text-xl font-semibold mb-4">导出PDF</h3>
      <div class="space-y-4">
        <div>
          <label class="block text-sm font-medium text-gray-700 mb-1">文件名</label>
          <input type="text" id="pdf-filename" class="input-field" value="简谱" placeholder="请输入文件名">
        </div>
        <div>
          <label class="block text-sm font-medium text-gray-700 mb-1">页面设置</label>
          <div class="grid grid-cols-2 gap-3">
            <div>
              <label class="block text-xs text-gray-500 mb-1">方向</label>
              <select id="pdf-orientation" class="input-field">
                <option value="portrait">纵向</option>
                <option value="landscape">横向</option>
              </select>
            </div>
            <div>
              <label class="block text-xs text-gray-500 mb-1">纸张大小</label>
              <select id="pdf-size" class="input-field">
                <option value="a4">A4</option>
                <option value="letter">Letter</option>
                <option value="legal">Legal</option>
              </select>
            </div>
          </div>
        </div>
        <div class="flex justify-end space-x-3 pt-2">
          <button id="cancel-export-btn" class="btn btn-outline">取消</button>
          <button id="confirm-export-btn" class="btn btn-secondary">确认导出</button>
        </div>
      </div>
    </div>
  </div>

  <script>
    // DOM元素引用
    const tempoSlider = document.getElementById('tempo');
    const tempoValue = document.getElementById('tempo-value');
    const notePad = document.getElementById('note-pad');
    const currentBar = document.getElementById('current-bar');
    const addBarBtn = document.getElementById('add-bar-btn');
    const clearBarBtn = document.getElementById('clear-bar-btn');
    const previewBars = document.getElementById('preview-bars');
    const exportBtn = document.getElementById('export-btn');
    const exportModal = document.getElementById('export-modal');
    const modalContent = document.getElementById('modal-content');
    const cancelExportBtn = document.getElementById('cancel-export-btn');
    const confirmExportBtn = document.getElementById('confirm-export-btn');
    const pdfFilename = document.getElementById('pdf-filename');
    const pdfOrientation = document.getElementById('pdf-orientation');
    const pdfSize = document.getElementById('pdf-size');
    const zoomInBtn = document.getElementById('zoom-in-btn');
    const zoomOutBtn = document.getElementById('zoom-out-btn');
    const resetZoomBtn = document.getElementById('reset-zoom-btn');
    const sheetPreview = document.getElementById('sheet-preview');
    
    // 表单输入元素
    const songTitle = document.getElementById('song-title');
    const composer = document.getElementById('composer');
    const lyricist = document.getElementById('lyricist');
    const keySignature = document.getElementById('key-signature');
    const timeSignature = document.getElementById('time-signature');
    
    // 预览区域对应的元素
    const previewTitle = document.getElementById('preview-title');
    const previewComposer = document.getElementById('preview-composer');
    const previewLyricist = document.getElementById('preview-lyricist');
    const previewKey = document.getElementById('preview-key');
    const previewTime = document.getElementById('preview-time');
    const previewTempo = document.getElementById('preview-tempo');
    
    // 状态变量
    let currentZoom = 80; // 初始缩放比例
    let bars = []; // 存储所有小节
    let lyrics = []; // 存储歌词
    
    // 更新速度显示
    tempoSlider.addEventListener('input', () => {
      tempoValue.textContent = `${tempoSlider.value} BPM`;
      previewTempo.textContent = `♩=${tempoSlider.value}`;
    });
    
    // 音符输入按钮事件
    notePad.addEventListener('click', (e) => {
      if (e.target.classList.contains('note-btn')) {
        const note = e.target.dataset.value;
        
        // 清除提示文本
        if (currentBar.querySelector('.text-gray-400')) {
          currentBar.innerHTML = '';
        }
        
        // 添加音符元素
        const noteElement = document.createElement('div');
        noteElement.className = 'note-input bg-white';
        noteElement.textContent = note;
        noteElement.dataset.value = note;
        currentBar.appendChild(noteElement);
        
        // 自动聚焦到新添加的音符
        noteElement.focus();
      }
    });
    
    // 清除当前小节
    clearBarBtn.addEventListener('click', () => {
      currentBar.innerHTML = '<span class="text-gray-400">点击上方音符添加...</span>';
    });
    
    // 添加小节到预览
    addBarBtn.addEventListener('click', () => {
      const notes = Array.from(currentBar.querySelectorAll('.note-input')).map(note => note.dataset.value);
      
      if (notes.length === 0) {
        alert('当前小节为空，请添加音符后再试！');
        return;
      }
      
      // 添加到小节列表
      bars.push(notes);
      
      // 更新预览
      updatePreview();
      
      // 清空当前小节
      currentBar.innerHTML = '<span class="text-gray-400">点击上方音符添加...</span>';
    });
    
    // 更新简谱预览
    function updatePreview() {
      // 如果没有小节，显示提示信息
      if (bars.length === 0) {
        previewBars.innerHTML = `
          <div class="text-center text-gray-400 italic py-12">
            请从左侧面板添加简谱内容...
          </div>
        `;
        return;
      }
      
      // 生成小节HTML
      let barsHtml = '';
      
      bars.forEach((bar, index) => {
        // 每5个小节换行
        if (index > 0 && index % 5 === 0) {
          barsHtml += '<div class="my-4"></div>';
        }
        
        // 生成小节中的音符
        let notesHtml = '';
        bar.forEach(note => {
          // 处理上下加点
          let displayNote = note;
          if (note.startsWith('·')) {
            displayNote = `<sup>${note[1]}</sup>${note.slice(2)}`;
          } else if (note.endsWith('·')) {
            displayNote = `${note.slice(0, -1)}<sub>${note[note.length-2]}</sub>`;
          }
          
          notesHtml += `<span class="inline-block px-1.5">${displayNote}</span>`;
        });
        
        barsHtml += `
          <div class="inline-block mr-2 last:mr-0">
            <div class="flex flex-col items-center">
              <div class="sheet-line w-full"></div>
              <div class="sheet-line w-full"></div>
              <div class="sheet-line w-full"></div>
              <div class="sheet-line w-full"></div>
              <div class="mt-1 text-center">${notesHtml}</div>
            </div>
          </div>
        `;
      });
      
      previewBars.innerHTML = barsHtml;
    }
    
    // 表单输入实时更新预览
    songTitle.addEventListener('input', () => {
      previewTitle.textContent = songTitle.value || '歌曲标题';
    });
    
    composer.addEventListener('input', () => {
      previewComposer.textContent = composer.value || '作曲者';
    });
    
    lyricist.addEventListener('input', () => {
      previewLyricist.textContent = lyricist.value || '作词者';
    });
    
    keySignature.addEventListener('change', () => {
      previewKey.textContent = `1=${keySignature.value}`;
    });
    
    timeSignature.addEventListener('change', () => {
      previewTime.textContent = timeSignature.value;
    });
    
    // 缩放控制
    zoomInBtn.addEventListener('click', () => {
      if (currentZoom < 150) {
        currentZoom += 10;
        sheetPreview.style.zoom = `${currentZoom}%`;
      }
    });
    
    zoomOutBtn.addEventListener('click', () => {
      if (currentZoom > 50) {
        currentZoom -= 10;
        sheetPreview.style.zoom = `${currentZoom}%`;
      }
    });
    
    resetZoomBtn.addEventListener('click', () => {
      currentZoom = 80;
      sheetPreview.style.zoom = `${currentZoom}%`;
    });
    
    // 导出PDF相关
    exportBtn.addEventListener('click', () => {
      // 检查是否有内容
      if (bars.length === 0) {
        alert('请先添加简谱内容再导出！');
        return;
      }
      
      // 设置默认文件名
      pdfFilename.value = songTitle.value || '简谱';
      
      // 显示对话框
      exportModal.classList.remove('hidden');
      setTimeout(() => {
        modalContent.classList.remove('scale-95', 'opacity-0');
        modalContent.classList.add('scale-100', 'opacity-100');
      }, 10);
    });
    
    cancelExportBtn.addEventListener('click', closeExportModal);
    
    function closeExportModal() {
      modalContent.classList.remove('scale-100', 'opacity-100');
      modalContent.classList.add('scale-95', 'opacity-0');
      setTimeout(() => {
        exportModal.classList.add('hidden');
      }, 300);
    }
    
    // 确认导出PDF
    confirmExportBtn.addEventListener('click', () => {
      const { jsPDF } = window.jspdf;
      const doc = new jsPDF({
        orientation: pdfOrientation.value,
        unit: 'mm',
        format: pdfSize.value
      });
      
      // 显示加载状态
      confirmExportBtn.disabled = true;
      confirmExportBtn.innerHTML = '<i class="fa fa-spinner fa-spin mr-1"></i> 导出中...';
      
      html2canvas(document.getElementById('sheet-content'), {
        scale: 2,
        useCORS: true,
        logging: false
      }).then(canvas => {
        const imgData = canvas.toDataURL('image/png');
        const imgWidth = doc.internal.pageSize.getWidth();
        const imgHeight = canvas.height * imgWidth / canvas.width;
        
        doc.addImage(imgData, 'PNG', 0, 0, imgWidth, imgHeight);
        doc.save(`${pdfFilename.value}.pdf`);
        
        // 恢复按钮状态
        confirmExportBtn.disabled = false;
        confirmExportBtn.innerHTML = '确认导出';
        
        // 关闭对话框
        closeExportModal();
      }).catch(error => {
        console.error('导出PDF失败:', error);
        alert('导出PDF失败，请重试！');
        
        // 恢复按钮状态
        confirmExportBtn.disabled = false;
        confirmExportBtn.innerHTML = '确认导出';
      });
    });
    
    // 初始化
    updatePreview();
  </script>
</body>
</html>
    